//package com.supconit.han;
//
//
//import java.io.IOException;
//import java.io.UncheckedIOException;
//import java.io.UnsupportedEncodingException;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.net.URL;
//import java.net.URLDecoder;
//import java.nio.charset.StandardCharsets;
//import java.nio.file.FileSystems;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.util.ArrayList;
//import java.util.Enumeration;
//import java.util.List;
//import java.util.Map;
//import java.util.function.Function;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//
//
//
///**
// * A simple classpath scan works both in directory and jar:
// *
// * https://stackoverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection#58773038
// */
//public class ResourceResolver {
//
//    Logger logger = LoggerFactory.getLogger(getClass());
//
//    String basePackage;
//
//    public ResourceResolver(String basePackage) {
//        this.basePackage = basePackage;
//    }
//
//    public <R> List<R> scan(Function<Resource, R> mapper) {
//        String basePackagePath = this.basePackage.replace(".", "/");
//        String path = basePackagePath;
//        try {
//            List<R> collector = new ArrayList<>();
//            scan0(basePackagePath, path, collector, mapper);
//            return collector;
//        } catch (IOException e) {
//            throw new UncheckedIOException(e);
//        } catch (URISyntaxException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//    <R> void scan0(String basePackagePath, String path, List<R> collector, Function<Resource, R> mapper) throws IOException, URISyntaxException {
//        logger.atDebug().log("scan path: {}", path);
//        Enumeration<URL> en = getContextClassLoader().getResources(path);
//        while (en.hasMoreElements()) {
//            URL url = en.nextElement();
//            URI uri = url.toURI();
//            String uriStr = removeTrailingSlash(uriToString(uri));
//            String uriBaseStr = uriStr.substring(0, uriStr.length() - basePackagePath.length());
//            if (uriBaseStr.startsWith("file:")) {
//                uriBaseStr = uriBaseStr.substring(5);
//            }
//            if (uriStr.startsWith("jar:")) {
//                scanFile(true, uriBaseStr, jarUriToPath(basePackagePath, uri), collector, mapper);
//            } else {
//                scanFile(false, uriBaseStr, Paths.get(uri), collector, mapper);
//            }
//        }
//    }
//
//    ClassLoader getContextClassLoader() {
//        ClassLoader cl = null;
//        cl = Thread.currentThread().getContextClassLoader();
//        if (cl == null) {
//            cl = getClass().getClassLoader();
//        }
//        return cl;
//    }
//
//    Path jarUriToPath(String basePackagePath, URI jarUri) throws IOException {
//        return FileSystems.newFileSystem(jarUri, Map.of()).getPath(basePackagePath);
//    }
//
//    <R> void scanFile(boolean isJar, String base, Path root, List<R> collector, Function<Resource, R> mapper) throws IOException {
//        String baseDir = removeTrailingSlash(base);
//        Files.walk(root).filter(Files::isRegularFile).forEach(file -> {
//            Resource res = null;
//            if (isJar) {
//                res = new Resource(baseDir, removeLeadingSlash(file.toString()));
//            } else {
//                String path = file.toString();
//                String name = removeLeadingSlash(path.substring(baseDir.length()));
//                res = new Resource("file:" + path, name);
//            }
//            logger.atDebug().log("found resource: {}", res);
//            R r = mapper.apply(res);
//            if (r != null) {
//                collector.add(r);
//            }
//        });
//    }
//
//    String uriToString(URI uri) {
//        try {
//            return URLDecoder.decode(uri.toString(), String.valueOf(StandardCharsets.UTF_8));
//        } catch (UnsupportedEncodingException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//    String removeLeadingSlash(String s) {
//        if (s.startsWith("/") || s.startsWith("\\")) {
//            s = s.substring(1);
//        }
//        return s;
//    }
//
//    String removeTrailingSlash(String s) {
//        if (s.endsWith("/") || s.endsWith("\\")) {
//            s = s.substring(0, s.length() - 1);
//        }
//        return s;
//    }
//}
//
//
//
//class AnnotationConfigApplicationContext {
//    Map<String, Object> beans;
//
//}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
